package com.generator.utils;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.generator.DTO.GeneratorDTO;
import com.generator.DTO.TemplateDTO;
import com.generator.entity.TableColumn;
import freemarker.template.Template;
import lombok.Data;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.sql.Types;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @version 1.0
 * @Author Xing
 * @Date 2023/8/9 20:36
 */
@Component
@ConfigurationProperties(prefix = "spring.datasource")
@Data
public class GeneratorUtils {
    private String url;
    private String driverClassName;
    private String username;
    private String password;

    public void generator(GeneratorDTO generator) {
        System.out.println(generator.getTableName());
        Thread.currentThread().setContextClassLoader(GeneratorUtils.class.getClassLoader());
        FastAutoGenerator.create(url, username, password)
                .globalConfig(builder -> {
                    builder.outputDir(generator.getUrl())
                            .author(generator.getAuthor())
                            .enableSwagger()
                            .disableOpenDir()
                            .dateType(DateType.ONLY_DATE);
                })
                .packageConfig(builder -> {
                    builder.parent("com.generator")
                            .mapper("dao")
                            .moduleName(generator.getModelName())
                            .pathInfo(Collections.singletonMap(OutputFile.xml, "src/main/resources/Mapper"))
                            .entity("entity")
                            .service("service")
                            .serviceImpl("service.impl")
                            .controller("controller");
                })
                .strategyConfig(builder -> {
                    builder.addInclude(generator.getTableName())
                            .addTablePrefix(generator.getTablePrefix())
                            .entityBuilder().enableFileOverride().enableLombok().enableFileOverride()
                            .naming(NamingStrategy.underline_to_camel).idType(getIdType(generator.getIdType()))
                            .mapperBuilder().enableFileOverride().enableFileOverride()
                            .serviceBuilder().formatServiceFileName("%sService")
                            .enableFileOverride().enableFileOverride()
                            .controllerBuilder().enableFileOverride().enableRestStyle().enableFileOverride();
                }).templateEngine(new FreemarkerTemplateEngine())
                .templateConfig(builder -> {
                    builder.controller("/templates/controller.java")
                            .service("/templates/service.java")
                            .serviceImpl("/templates/serviceImpl.java")
                            .mapper("/templates/dao.java")
                            .entity("/templates/entity.java")
                            .xml("/templates/mapper.xml");
                }).dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
                    int typeCode = metaInfo.getJdbcType().TYPE_CODE;
                    if (typeCode == Types.SMALLINT) {
                        // 自定义类型转换
                        return DbColumnType.INTEGER;
                    }
                    return typeRegistry.getColumnType(metaInfo);
                }))
                .execute();
        System.out.println(123);
    }

    public IdType getIdType(String idType) {
        if (idType.equals("雪花算法")) {
            return IdType.NONE;
        } else if (idType.equals("UUID")) {
            return IdType.ASSIGN_UUID;
        } else if (idType.equals("ID自增")) {
            return IdType.AUTO;
        } else if (idType.equals("idWorker")) {
            return IdType.ASSIGN_ID;
        }
        return IdType.NONE;
    }


    public String getContent(String info, TemplateDTO dto){
        if (ObjectUtils.isEmpty(dto)){
            return info;
        }
        StringReader reader = new StringReader(info);
        StringWriter stringWriter = new StringWriter();
        try {
            Template template = new Template(dto.toString(), reader, null, "utf-8");
            template.process(dto,stringWriter);
        }catch (Exception e){
            e.fillInStackTrace();
            System.out.println(e);
        }
        info = stringWriter.toString();
        IOUtils.closeQuietly(reader);
        IOUtils.closeQuietly(stringWriter);
        return info;
    }

    public List<TableColumn> getColumn(List<TableColumn> list){
        for (TableColumn column : list) {
            column.setDataType(getColumnName(column.getDataType()));
        }
        return list;
    }

    public String getColumnName(String dataType){
        if (dataType.equals("text")||dataType.equals("varchar")){
            return "String";
        }else if(dataType.equals("int")){
            return "Integer";
        }else if(dataType.equals("bigint")){
            return "Long";
        }else if(dataType.equals("decimal")||dataType.equals("float")){
            return "Double";
        }else{
            return "Object";
        }
    }

}
